package com.ruoyi.door.service;

import java.util.List;
import java.util.Map;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.door.controller.admin.adsl.vo.DoorAdslRespVO;
import com.ruoyi.door.controller.admin.adsl.vo.proxy.DoorAdslRespVOProxy;
import com.ruoyi.door.controller.admin.repair.vo.*;
import com.ruoyi.door.mapper.DoorRepairOrderMapper;
import com.ruoyi.door.domain.DoorAdsl;
import com.ruoyi.door.domain.DoorHouse;
import com.ruoyi.door.domain.DoorRepairOrderLog;
import com.ruoyi.door.enums.RepairOrderStatusEnum;
import com.ruoyi.door.utils.WxTemplate;
import com.ruoyi.door.utils.map.BaiduMapUtils;
import com.ruoyi.door.utils.map.PositionUtil;
import com.ruoyi.door.domain.DoorRepairOrder;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.constant.HttpStatus;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.easy.query.api.proxy.client.EasyEntityQuery;

/**
 * 报修工单Service业务层处理
 *
 * @author ruoyi
 * @date 2025-07-29
 */
@Service
public class DoorRepairOrderService {
    @Autowired
    private EasyEntityQuery easyEntityQuery;
    @Autowired
    private DoorRepairOrderMapper doorRepairOrderMapper;
    @Autowired
    private WxTemplate wxTemplate;
    /**
     * 查询报修工单
     *
     * @param id 报修工单主键
     * @return 报修工单
     */
    public DoorRepairOrder selectDoorRepairOrderById(Long id) {
        return easyEntityQuery.queryable(DoorRepairOrder.class).where(x -> x.id().eq(id))
                .firstOrNull();
    }

    /**
     * 查询报修工单列表
     *
     * @param doorRepairOrder 报修工单
     * @return 报修工单
     */
    public TableDataInfo selectDoorRepairOrderPageList(DoorRepairOrderPageReqVO doorRepairOrder, Long userId) {
        // 使用 PageHelper 进行分页
        PageHelper.startPage(TableSupport.buildPageRequest().getPageNum(), TableSupport.buildPageRequest().getPageSize());
        List<DoorRepairOrderRespVO> list = doorRepairOrderMapper.selectDoorRepairOrderList(doorRepairOrder, userId);
        PageInfo<DoorRepairOrderRespVO> pageInfo = new PageInfo<>(list);
        
        // 创建并返回 TableDataInfo
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(pageInfo.getTotal());
        return rspData;
    }

    public List<DoorRepairOrderRespVO> selectDoorRepairOrderList(DoorRepairOrderPageReqVO doorRepairOrder, Long userId) {
        return doorRepairOrderMapper.selectDoorRepairOrderList(doorRepairOrder, userId);
    }


    /**
     * 新增报修工单
     *
     * @param reqVO 报修工单
     * @return 结果
     */
    public long insertDoorRepairOrder(DoorRepairOrderCreateReqVO reqVO, Long userId, String userType) {
        DoorRepairOrder doorRepairOrder = new DoorRepairOrder();
        doorRepairOrder.setCreateTime(DateUtils.getNowDate());
        doorRepairOrder.setCreateBy(String.valueOf(userId));
        doorRepairOrder.setCreateUserType(userType);
        doorRepairOrder.setStatus(RepairOrderStatusEnum.WAIT.getValue());
        doorRepairOrder.setCreatePhone(reqVO.getCreatePhone());
        doorRepairOrder.setAdslId(reqVO.getAdslId());
        doorRepairOrder.setRepairContent(reqVO.getRepairContent());
        doorRepairOrder.setRepairType(reqVO.getRepairType());
        doorRepairOrder.setRepairImgs(reqVO.getRepairImgs());

        long l = easyEntityQuery.insertable(doorRepairOrder).executeRows(true);

        DoorRepairOrderLog doorRepairOrderLog = new DoorRepairOrderLog();
        doorRepairOrderLog.setRepairOrderId(doorRepairOrder.getId());
        doorRepairOrderLog.setCreateTime(DateUtils.getNowDate());
        doorRepairOrderLog.setCreateBy(String.valueOf(userId));
        doorRepairOrderLog.setCreateUserType(userType);
        doorRepairOrderLog.setStatus(RepairOrderStatusEnum.WAIT.getValue());

        easyEntityQuery.insertable(doorRepairOrderLog).executeRows();
        return l;
    }

    /**
     * 修改报修工单
     *
     * @param reqVO 报修工单
     * @return 结果
     */
    public long updateDoorRepairOrder(DoorRepairOrderUpdateReqVO reqVO) {
        DoorRepairOrder doorRepairOrder = easyEntityQuery.queryable(DoorRepairOrder.class).where(x -> x.id().eq(reqVO.getRepairOrderId()))
                .firstOrNull();
        doorRepairOrder.setUpdateTime(DateUtils.getNowDate());
        doorRepairOrder.setAdslId(reqVO.getAdslId());
        doorRepairOrder.setRepairContent(reqVO.getRepairContent());
        doorRepairOrder.setRepairType(reqVO.getRepairType());
        doorRepairOrder.setResponseContent(reqVO.getResponseContent());
        doorRepairOrder.setRepairImgs(reqVO.getRepairImgs());
        doorRepairOrder.setCreatePhone(reqVO.getCreatePhone());
        return easyEntityQuery.updatable(doorRepairOrder).executeRows();
    }

    /**
     * 批量删除报修工单
     *
     * @param ids 需要删除的报修工单主键
     * @return 结果
     */
    public long deleteDoorRepairOrderByIds(Long[] ids) {
        return easyEntityQuery.deletable(DoorRepairOrder.class)
                .disableLogicDelete()//禁用逻辑删除,使用物理删除
                .allowDeleteStatement(true)//如果不允
                .where(x -> x.id().in(ids))
                .executeRows();
    }

    /**
     * 删除报修工单信息
     *
     * @param id 报修工单主键
     * @return 结果
     */
    public long deleteDoorRepairOrderById(Long id) {
        return easyEntityQuery.deletable(DoorRepairOrder.class)
                .disableLogicDelete()//禁用逻辑删除,使用物理删除
                .allowDeleteStatement(true)//如果不允
                .where(x -> x.id().eq(id))
                .executeRows();

    }


    public long assign(DoorRepairOrderAssignReqVO reqVO, Long userId, String userType) {
        DoorRepairOrder doorRepairOrder = easyEntityQuery.queryable(DoorRepairOrder.class).where(x -> x.id().eq(reqVO.getRepairOrderId()))
                .firstOrNull();
        doorRepairOrder.setOperaUserId(reqVO.getOperaUserId());
        doorRepairOrder.setStatus(RepairOrderStatusEnum.SEND.getValue());
        doorRepairOrder.setUpdateTime(DateUtils.getNowDate());
        doorRepairOrder.setOperaPhone(reqVO.getOperaPhone());
        SysUser sysUser = easyEntityQuery.queryable(SysUser.class).where(s -> s.userId().eq(reqVO.getOperaUserId())).firstOrNull();
        SysUser sysUser2 = easyEntityQuery.queryable(SysUser.class).where(s -> s.userId().eq(Long.valueOf(doorRepairOrder.getCreateBy()))).firstOrNull();

        DoorRepairOrderLog doorRepairOrderLog = new DoorRepairOrderLog();
        doorRepairOrderLog.setRepairOrderId(doorRepairOrder.getId());
        doorRepairOrderLog.setCreateTime(DateUtils.getNowDate());
        doorRepairOrderLog.setCreateBy(String.valueOf(userId));
        doorRepairOrderLog.setCreateUserType(userType);
        doorRepairOrderLog.setStatus(RepairOrderStatusEnum.SEND.getValue());
        doorRepairOrderLog.setLog("指派给" + sysUser.getNickName() + "处理");
        easyEntityQuery.insertable(doorRepairOrderLog).executeRows();
        if (StrUtil.isNotEmpty(sysUser.getOpenid())){
            String address = "";
            DoorAdsl doorAdsl = easyEntityQuery.queryable(DoorAdsl.class).where(x -> x.id().eq(doorRepairOrder.getAdslId()))
                    .firstOrNull();
            if (doorAdsl!=null){
                DoorHouse doorHouse = easyEntityQuery.queryable(DoorHouse.class).where(x -> x.id().eq(doorAdsl.getHouseId()))
                        .firstOrNull();
                if (doorHouse!=null){
                    address=doorHouse.getAddress();
                }
            }
            wxTemplate.gongdan("RePair"+doorRepairOrder.getId(),sysUser.getOpenid()
            , DateUtil.format(doorRepairOrder.getCreateTime(),"yyyy-MM-dd HH:mm:ss"),
                    "【"+doorRepairOrder.getRepairType()+"】"+doorRepairOrder.getRepairContent(),
                    sysUser2.getNickName(),address,doorRepairOrder.getCreatePhone());
        }
        return easyEntityQuery.updatable(doorRepairOrder).executeRows();
    }

    /**
     * 接收工单
     *
     * @param reqVO    接收信息
     * @param userId   用户ID
     * @param userType 用户类型
     * @return 结果
     */
    public long receive(DoorRepairOrderReceiveReqVO reqVO, Long userId, String userType) {
        DoorRepairOrder doorRepairOrder = easyEntityQuery.queryable(DoorRepairOrder.class).where(x -> x.id().eq(reqVO.getRepairOrderId()))
                .firstOrNull();
        if (ObjectUtil.isNull(doorRepairOrder)) {
            throw new RuntimeException("工单不存在");
        }
        if (!RepairOrderStatusEnum.SEND.getValue().equals(doorRepairOrder.getStatus())) {
            throw new RuntimeException("工单状态不是已派单");
        }
        doorRepairOrder.setStatus(RepairOrderStatusEnum.receive.getValue());
        doorRepairOrder.setUpdateTime(DateUtils.getNowDate());

        // 添加日志
        DoorRepairOrderLog doorRepairOrderLog = new DoorRepairOrderLog();
        doorRepairOrderLog.setRepairOrderId(doorRepairOrder.getId());
        doorRepairOrderLog.setCreateTime(DateUtils.getNowDate());
        doorRepairOrderLog.setCreateBy(String.valueOf(userId));
        doorRepairOrderLog.setCreateUserType(userType);
        doorRepairOrderLog.setStatus(RepairOrderStatusEnum.receive.getValue());
//        doorRepairOrderLog.setImg(reqVO.getImg());
//        doorRepairOrderLog.setLog(reqVO.getLog());
//        doorRepairOrderLog.setLongitude(reqVO.getLongitude());
//        doorRepairOrderLog.setLatitude(reqVO.getLatitude());
        easyEntityQuery.insertable(doorRepairOrderLog).executeRows();

        return easyEntityQuery.updatable(doorRepairOrder).executeRows();
    }

    /**
     * 完成工单
     *
     * @param reqVO    完成信息
     * @param userId   用户ID
     * @param userType 用户类型
     * @return 结果
     */
    public long complete(DoorRepairOrderCompleteReqVO reqVO, Long userId, String userType) {
        DoorRepairOrder doorRepairOrder = easyEntityQuery.queryable(DoorRepairOrder.class).where(x -> x.id().eq(reqVO.getRepairOrderId()))
                .firstOrNull();
        if (ObjectUtil.isNull(doorRepairOrder)) {
            throw new RuntimeException("工单不存在");
        }
        if (!RepairOrderStatusEnum.receive.getValue().equals(doorRepairOrder.getStatus())) {
            throw new RuntimeException("工单状态不是已接单");
        }
        DoorAdslRespVO doorAdslRespVO = easyEntityQuery.queryable(DoorAdsl.class)
                .leftJoin(DoorHouse.class, (d, h) -> d.houseId().eq(h.id()))
                .leftJoin(SysUser.class, (d, h, u) -> u.userId().eq(h.landlordId()))
                .leftJoin(SysDept.class, (d, h, u, d1) -> h.country().eq(d1.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2) -> h.province().eq(d2.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2, d3) -> h.city().eq(d3.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2, d3, d4) -> h.district().eq(d4.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2, d3, d4, d5) -> h.street().eq(d5.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2, d3, d4, d5, d6) -> h.village().eq(d6.deptId()))
                .where((d, d2, s3, s4, s5, s6, s7, s8, s9) -> d.id().eq(doorRepairOrder.getAdslId()))
                .select((d1, h, u, s4, s5, s6, s7, s8, s9) -> {
                    DoorAdslRespVOProxy r = new DoorAdslRespVOProxy();//在BanCardVO上添加@EntityProxy注解build时会生成对应的Proxy对象
                    r.selectAll(d1);
                    r.door().set(h.door());
                    r.monthPrice().set(h.monthPrice());
                    r.startDate().set(h.startDate());
                    r.endDate().set(h.endDate());
                    r.countryName().set(s4.deptName());
                    r.provinceName().set(s5.deptName());
                    r.cityName().set(s6.deptName());
                    r.districtName().set(s7.deptName());
                    r.streetName().set(s8.deptName());
                    r.villageName().set(s9.deptName());
                    r.address().set(h.address());
                    r.landlordName().set(u.nickName());
                    r.landlordPhone().set(u.phonenumber());
                    return r;
                }).firstOrNull();

        doorRepairOrder.setStatus(RepairOrderStatusEnum.OK.getValue());
        doorRepairOrder.setResponseContent(reqVO.getLog());
        doorRepairOrder.setUpdateTime(DateUtils.getNowDate());

        // 添加日志
        DoorRepairOrderLog doorRepairOrderLog = new DoorRepairOrderLog();
        doorRepairOrderLog.setRepairOrderId(doorRepairOrder.getId());
        doorRepairOrderLog.setCreateTime(DateUtils.getNowDate());
        doorRepairOrderLog.setCreateBy(String.valueOf(userId));
        doorRepairOrderLog.setCreateUserType(userType);
        doorRepairOrderLog.setStatus(RepairOrderStatusEnum.OK.getValue());
        doorRepairOrderLog.setImg(reqVO.getImg());
        doorRepairOrderLog.setLog(reqVO.getLog());
        doorRepairOrderLog.setLongitude(reqVO.getLongitude());
        doorRepairOrderLog.setLatitude(reqVO.getLatitude());

        if (ObjectUtil.isNotNull(doorAdslRespVO)) {
            Map<String, Double> lngAndLat = BaiduMapUtils.getLngAndLat(doorAdslRespVO.getCountryName() +
                    doorAdslRespVO.getProvinceName() + doorAdslRespVO.getCityName() +
                    doorAdslRespVO.getDistrictName() + doorAdslRespVO.getStreetName() +
                    doorAdslRespVO.getVillageName() + doorAdslRespVO.getAddress());
            if (ObjectUtil.isNotNull(lngAndLat.get("lng"))) {
                double distance1 = PositionUtil.getDistance1(lngAndLat.get("lng"), lngAndLat.get("lat"), reqVO.getLongitude(), reqVO.getLatitude());
                doorRepairOrderLog.setDistance(distance1);
                doorRepairOrderLog.setHouseLatitude(lngAndLat.get("lat"));
                doorRepairOrderLog.setHouseLongitude(lngAndLat.get("lng"));
            }

        }

        easyEntityQuery.insertable(doorRepairOrderLog).executeRows();

        return easyEntityQuery.updatable(doorRepairOrder).executeRows();
    }

    public int delete(DoorRepairOrderCompleteReqVO reqVO) {
        easyEntityQuery.deletable(DoorRepairOrderLog.class)
                .allowDeleteStatement(true)//如果不允)
                .disableLogicDelete()
                .where(d ->  d.repairOrderId().eq(reqVO.getRepairOrderId())).executeRows();
        easyEntityQuery.deletable(DoorRepairOrder.class)
                .allowDeleteStatement(true)//如果不允)
                .disableLogicDelete()
                .where(d ->  d.id().eq(reqVO.getRepairOrderId())).executeRows();
        return  1;
    }
}